package mws.redis.src.aop;

import lombok.RequiredArgsConstructor;
import mws.redis.src.util.RedisUtils;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.UUID;


@Aspect
@Component
@RequiredArgsConstructor
public class RedisAop {

    private final RedisUtils redisTemplateOfString;

    // 定义切入点，例如拦截带有@RedisLock注解的方法
    @Around("@annotation(redisLockAnnotation)")
    public Object redisLock(ProceedingJoinPoint joinPoint, RedisLock redisLockAnnotation) throws Throwable {
        // 获取锁的键名（从注解参数或方法参数中获取）
        String lockKey = redisLockAnnotation.key();


        String value = redisLockAnnotation.value();
        // 生成唯一标识，用于释放锁时的验证

        int expire = redisLockAnnotation.expire();

        String requestId = UUID.randomUUID().toString();

        try {
            // 尝试获取Redis锁，设置过期时间防止死锁
            boolean locked = redisTemplateOfString.setAbsent(lockKey,value,expire);

            if (locked) {
                // 获取锁成功，执行目标方法
                return joinPoint.proceed();
            } else {
                // 获取锁失败，可根据需求处理（抛异常或返回特定结果）
                throw new RuntimeException("获取分布式锁失败，当前有其他线程在执行");
            }
        } finally {
            // 释放锁（确保只有持有锁的线程才能释放）
            if (Objects.equals(requestId, redisTemplateOfString.get(lockKey))) {
                redisTemplateOfString.delete(lockKey);
            }
        }
    }

}
